
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>高级 Kubernetes 部署策略</title>
            </head>
            <body>
            <a href="https://andyoung.blog.csdn.net">原作者博客</a>
            <div id="content_views" class="markdown_views prism-atom-one-light">
                    <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                        <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                    </svg>
                    <p>在现代技术领域，Kubernetes 是一个采用非常广泛的平台。它让组织能够大规模部署和管理应用程序。这一容器编排平台极大的简化了基于微服务的应用程序的基础架构配置工作，并通过模块化设计实现了高效的负载管理。Kubernetes 支持各种部署资源，以帮助运维人员使用更新和版本控制来实现 CI/CD 管道。虽然 Kubernetes 提供了滚动更新作为默认部署策略，但一些用例需要非常规方法来部署或更新集群服务。</p> 
<p>本文回顾了 Kubernetes 部署中的几个概念，并深入探讨了各种高级 Kubernetes 部署策略、优缺点和用例。</p> 
<h2><a id="1_Kubernetes__4"></a>1. Kubernetes 部署概念</h2> 
<p>Kubernetes 使用部署资源，以声明方式更新应用程序。通过部署，集群管理员定义应用程序的生命周期，定义应用程序执行相关更新的方式。Kubernetes 部署提供了一种自动化方式来实现和维护集群对象和应用程序所需的状态。Kubernetes 后端无需人工干预即可管理部署过程，提供了一种安全且可重复的方式来执行应用程序更新工作。</p> 
<p>Kubernetes 部署允许集群管理员：</p> 
<ul><li>部署 pod 或副本集</li><li>更新副本集和 pod</li><li>回滚到早期版本</li><li>暂停 / 继续部署</li><li>扩展部署</li></ul> 
<p>以下部分将探讨 Kubernetes 如何简化容器化应用程序的更新过程，以及它如何解决持续交付的挑战。</p> 
<h2><a id="2_Kubernetes__18"></a>2. Kubernetes 对象</h2> 
<p>Kubernetes 利用许多负载资源对象，将它们作为持久实体来管理集群状态。Kubernetes API 使用 Deployment、ReplicaSet、StatefulSet 和 DaemonSet 资源对应用程序进行声明式更新。</p> 
<h3><a id="_22"></a>部署</h3> 
<p>Deployment（部署）是一种 Kubernetes 资源，用于定义和识别应用程序的所需状态。集群管理员在部署的 YAML 文件中描述了所需的状态，部署控制器使用该文件将实际状态逐渐更改为所需的状态。为了确保高可用性，部署控制器还不断对过程进行监控，并用健康的集群节点和 pod 替换失败的集群节点和 pod。</p> 
<h3><a id="_26"></a>副本集</h3> 
<p>ReplicaSet（副本集）用于维护特定数量的 pod，以确保高可用性。ReplicaSet 的清单（manifest）文件包括以下字段：</p> 
<ul><li>用于识别属于该集合的 pod 有哪些的选择器（selector）</li><li>副本数，表示集合中应该有多少个 pod</li><li>一个 pod 模板，用于显示新 pod 应创建哪些数据以满足 ReplicaSet 的标准</li></ul> 
<h3><a id="_34"></a>有状态集</h3> 
<p>StatefulSet（有状态集）对象管理有状态应用程序中 pod 的部署和扩展。该资源基于相同的容器规范管理 pod，然后确保一组 pod 的适当排序和唯一性。StatefulSet 的持久 pod 标识符让集群管理员能够将其负载连接到具有可用性保证的持久存储卷。</p> 
<h3><a id="_38"></a>守护程序集</h3> 
<p>DaemonSets（守护程序集）确保一组节点运行一个 pod 副本，从而帮助维护应用程序部署。DaemonSet 资源主要用于管理各种代理的部署和生命周期，例如：</p> 
<ul><li>每个节点上的集群存储代理</li><li>日志收集守护进程</li><li>节点监控守护进程</li></ul> 
<p>可以在此处（https://kubernetes.io/docs/concepts/workloads/controllers/）找到有关各种 Kubernetes 负载资源列表的详细信息。</p> 
<h2><a id="3__48"></a>3. 使用部署进行更新</h2> 
<p>Kubernetes 部署提供了一种可预测的方法来启动和停止 pod。这些资源让管理人员可以更轻松地迭代和自主部署、回滚更改和管理软件发布周期。Kubernetes 提供了各种部署策略来实现更小、更频繁的更新，因为它们提供了以下好处：</p> 
<ul><li>更快的客户反馈以获得更好的特性优化</li><li>缩短上市时间</li><li>提高 DevOps 团队的生产力</li></ul> 
<p>默认情况下，Kubernetes 提供滚动更新作为标准部署策略，该策略每次用一个新版本替换一个 pod，以避免集群停机。除此之外，根据特性的目标和类型，Kubernetes 还支持各种高级部署策略——包括蓝绿、金丝雀和 A/B 部署。</p> 
<p>让我们仔细看看这些策略分别提供了什么内容以及它们之间的区别。</p> 
<h2><a id="4_Kubernetes__60"></a>4. Kubernetes 部署的高级策略</h2> 
<p>Kubernetes 提供多种方式来发布应用程序更新和特性，具体取决于所涉及的用例和负载。在实时生产环境中，将部署配置与路由特性结合使用是非常重要的，这样更新就只会影响特定版本。这使发布团队能够在提交完整版本之前测试实时环境中更新特性的有效性。Kubernetes 支持多种高级部署策略，以便开发人员可以精确控制流向特定版本的流量。</p> 
<h3><a id="_64"></a>蓝绿部署</h3> 
<p>在蓝绿策略中，应用程序的新旧实例同时部署。用户可以访问现有版本（蓝色），而新版本（绿色）可供相同数量的实例供站点可靠性工程（SRE）和 QA 团队使用。一旦 QA 团队确认绿色版本通过了所有测试要求，用户就会被重定向到新版本。这是通过更新负载均衡服务的选择器字段中的版本标签来实现的。</p> 
<p>当开发人员想要避免版本控制问题时，蓝绿部署最合适。</p> 
<h4><a id="_70"></a>使用蓝绿部署策略</h4> 
<p>让我们假设应用程序的第一个版本是 v1.0.0，而可用的第二个版本是 v2.0.0。</p> 
<p>下面是指向第一个版本的服务：</p> 
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: darwin-service-a
spec:
  type: LoadBalancer
  selector:
    app: nginx
    version: v1.0.0
  ports:
       - name: http
         port: 80
         targetPort: 80
</code></pre> 
<p>下面是指向第二个版本的服务：</p> 
<pre><code>Version: v1
kind: Service
metadata:
  name: darwin-service-b
spec:
  type: LoadBalancer
  selector:
    app: nginx
    version: v2.0.0
  ports:
       - name: http
         port: 80
         targetPort: http
</code></pre> 
<p>请求的测试执行且第二个版本被许可后，第一个版本的 selector 就被改为 v2.0.0：</p> 
<pre><code>apiVersion: v1
kind: Service
metadata:
  name: darwin-service-a
spec:
  type: LoadBalancer
  selector:
    app: nginx
    version: v2.0.0
  ports:
       - name: http
         port: 80
         targetPort: http
</code></pre> 
<p>如果应用程序按预期运行，v1.0.0 将被丢弃。</p> 
<h3><a id="_130"></a>金丝雀部署</h3> 
<p>在金丝雀策略中，一部分用户被路由到托管新版本的 pod。该子集逐渐增加，而连接到旧版本的子集则减少。该策略会对比连接到两个版本的用户子集。如果未检测到错误，则将新版本推送给其余用户。</p> 
<h4><a id="_134"></a>使用金丝雀部署策略</h4> 
<p>原生 Kubernetes 金丝雀部署过程涉及以下内容：</p> 
<p>通过以下方式部署运行版本 1 所需数量的副本：</p> 
<p>部署第一个应用程序：</p> 
<pre><code>$ kubectl apply -f darwin-v1.yaml
</code></pre> 
<p>将其扩展到所需数量的副本：</p> 
<pre><code>$ kubectl scale --replicas=9 deploy darwin-v1
</code></pre> 
<p>部署版本 2 的一个实例：</p> 
<pre><code>$ kubectl apply -f darwin-v2.yaml
</code></pre> 
<p>如第二个版本成功部署，则对其进行测试：</p> 
<pre><code>$ service=$(minikube service darwin --url)$ while sleep 0.1; do curl "$service"; done
</code></pre> 
<p>如果部署成功，扩展版本 2 的实例数量：</p> 
<pre><code>$ kubectl scale --replicas=10 deploy darwin-v2
</code></pre> 
<p>当所有副本上线后，就可以优雅地删除第一个版本：</p> 
<pre><code>$ kubectl delete deploy darwin-v1
</code></pre> 
<h3><a id="AB__176"></a>A/B 部署</h3> 
<p>通过 A/B 部署，管理员可以将特定的用户子集路由到具有一些限制和 / 或条件的较新版本上。这些部署主要用于评估用户群对某些特性的响应。A/B 部署也被称为“暗启动”，因为用户在测试期间不了解应用包含哪些新特性。</p> 
<h4><a id="_AB__180"></a>使用 A/B 部署策略</h4> 
<p>以下是使用 Istio 服务网格执行 A/B 测试的方法，能够使用流量权重推送不同版本：</p> 
<ol><li>假设集群上已经安装了 Istio，第一步是部署两个版本的应用：</li></ol> 
<pre><code>$ kubectl apply -f darwin-v1.yaml -f darwin-v2.yaml
</code></pre> 
<ol start="2"><li>然后可以通过 Istio 网关公开这些版本，使用以下命令将请求匹配到第一个服务：</li></ol> 
<pre><code>$ kubectl apply -f ./gateway.yaml -f ./virtualservice.yaml
</code></pre> 
<ol start="3"><li>然后可以使用以下命令根据权重应用 Istio VirtualService 规则：</li></ol> 
<pre><code>$ kubectl apply -f ./virtualservice-weight.yaml
</code></pre> 
<p>这会以 1:10 的比例在版本之间分配流量权重。要转移流量权重，可编辑每个服务的权重，然后通过 Kubernetes CLI 更新 VirtualService 规则。</p> 
<h2><a id="5__204"></a>5. 何时使用每种高级部署策略</h2> 
<p>由于 Kubernetes 用例因可用性要求、预算限制、可用资源和其他考虑因素而异，因此没有一种万能的部署策略。在选择正确的部署策略时，需要考虑以下几点：</p> 
<p>对比 Kubernetes 部署策略</p> 
<p>蓝绿策略</p> 
<ul><li>特点：专注于渐进式交付，这对于在应用程序后端测试特性是非常重要的。</li><li>优点：实现即时推送和回滚；允许管理员在一次升级中更改整个集群的状态；消除版本控制问题。</li><li>缺点：在生产发布之前需要两倍数量的资源和适当的平台测试。</li></ul> 
<p>金丝雀策略</p> 
<ul><li>特点：在用户仍在运行旧版本的实例时测试新版本；被认为是避免 API 版本控制问题的最佳选择。</li><li>优点：通过错误率对比可方便监控性能表现；实现快速回滚；包含用户体验测试。</li><li>缺点：微调流量分布的成本很高；推送速度较慢。</li></ul> 
<p>A/B 策略</p> 
<ul><li>特点：向用户提供新旧应用程序版本，然后对比它们的体验；主要用于前端部署和 QA 测试流程不足的情况。</li><li>优点：允许多个版本并行运行；实现性能监控。</li><li>缺点：导致部署缓慢；带来了代价高昂的流量均衡。</li></ul> 
<h2><a id="6____228"></a>6. 总 结</h2> 
<p>Kubernetes 对象是该技术的核心功能之一，可快速交付应用程序更新和特性。借助部署资源，Kubernetes 管理员可以建立一个高效的版本控制系统来管理各个版本，同时将应用程序停机时间降至最低，甚至为零。部署允许管理员更新 pod、回滚到早期版本或扩展基础架构，以支持不断增长的负载。</p> 
<p>本文介绍的各项高级 Kubernetes 部署策略还让管理员能够将流量和请求路由到特定版本，从而进行实时测试和错误处理。这些策略可用于确保在管理员和开发人员完全提交更改之前，新特性能按计划工作。虽然部署资源构成了持久化应用程序状态的基础，但建议大家努力选择正确的部署策略，准备足够的回滚选项，并认真对待依赖于多个松散耦合服务的生态系统的动态特性。</p> 
<h2><a id="7_____234"></a>7. 资 源</h2> 
<ul><li> <p>使用 kubetctl 创建部署</p> <p>（https://kubernetes.io/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/）</p> </li><li> <p>Kubernetes 部署用例</p> <p>（https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#use-case）</p> </li><li> <p>Kubernetes 部署生命周期状态</p> <p>（https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#deployment-status）</p> </li></ul>
                </div>
            </body>
            </html>
            